home *** CD-ROM | disk | FTP | other *** search
- #import "Body.h"
-
- @implementation Body
-
- - init
- {
- [super init];
-
- bodyDelta = maskDelta = 1; //must not be < 1
- maskDist = bodyDist = 1;
- currentBodyListIndex = 0;
- bodyFrameIndexCounter = maskFrameIndexCounter = 0;
- bodyFrameRect.origin.x = 0.0;
- bodyFrameRect.origin.y = 0.0;
- maskFrameRect.origin.x = 0.0;
- maskFrameRect.origin.y = 0.0;
- firstState = YES;
-
- return self;
- }
-
- - (BOOL)doUntilDone
- {
- BOOL maskDone;
- maskDone = NO;
- if(firstState){
- currentImage = [self setBodyImage];
- [self setFrameRectForBody]; //set frame size
- [self setFrameRectForMask];
- [self setStartPosition:centerOfScreen]; //first body and mask position
-
- firstState = NO;
-
- [self drawBody];
- [self setImageListIndex];
- currentImage = [self setBodyImage];
- [self setFrameRectForBody]; //set frame size
- bodyPosition = [self adjustPositionForBody: bodyPosition];
- }
- else {
-
- maskDone = [self eraseBody];
- [self setFrameRectForMask];
- maskPosition = [self adjustPositionForMask: maskPosition];
- //draw body
- [self drawBody];
- [self setImageListIndex];
- currentImage = [self setBodyImage];
- [self setFrameRectForBody]; //set frame size
- bodyPosition = [self adjustPositionForBody: bodyPosition];
- }
-
- if(maskDone){
- return YES; //this body done
- }
- else{
- return NO;
- }
- }
- - setImageListIndex
- {
- currentBodyListIndex = floor((bodyFrameIndexCounter * frameDelta) *
- (bodyFrameIndexCounter * frameDelta) *
- (bodyFrameIndexCounter * frameDelta) *
- (bodyFrameIndexCounter * frameDelta));
- bodyFrameIndexCounter++;
- if(currentBodyListIndex >= numberOfFrames - 1)
- currentBodyListIndex = numberOfFrames - 1;
- return self;
- }
-
-
- // 4
- //uses X to make expotential curve for calculating movement of object
- //idea was to start slow and speed up expotentially
- //the smaller the value of objectSpeed the faster the object moves
- //I.E. if the number is 2 then it take 2 steps to move the whole distance
- - setObjectSpeed:(float)objectSpeed
- {
- float radius,x,y;
-
-
- x = bounds.size.width;
- y = bounds.size.height;
- radius = (sqrt(x*x + y*y))/2; // of screen bounds
-
- distDelta = (sqrt(sqrt(radius)))/(1 + objectSpeed);
-
- frameDelta = (sqrt(sqrt(numberOfFrames)))/(1 + objectSpeed);
-
- return self;
- }
-
- - free
- {
- return [super free];
- }
-
- - (NXImage *)setBodyImage
- {
- return ([imageList objectAt:currentBodyListIndex]);
-
- }
-
- - setImageList:(List *)list
- {
-
- imageList = list;
- return self;
- }
-
- - setMaskList:(List *)list
- {
- maskList = list;
- return self;
- }
-
- - setNumberOfFrames
- {
- numberOfFrames = [imageList count];
- return self;
- }
- - setStartPosition:(NXPoint)point //where body starts out
- {
- bodyPosition.x = point.x - floor((bodyFrameRect.size.width / 2));
- bodyPosition.y = point.y - floor((bodyFrameRect.size.height / 2));
- maskPosition.x = point.x - floor((maskFrameRect.size.width / 2));
- maskPosition.y = point.y - floor((maskFrameRect.size.height / 2));
- return self;
- }
-
-
- - setStarsOutlet: (id)starsOutlet
- {
- starsObject = starsOutlet;
- return self;
- }
-
- - setFrameRectForBody
- {
- NXSize size;
- [currentImage getSize: &size];
-
- //adjust the rectangle to reflect actual image that was built
- // so that you know when it actually crosses the viewscreen
-
- bodyFrameRect.origin.x = 8.0;
- bodyFrameRect.origin.y = 8.0;
- bodyFrameRect.size.width = size.width-16;
- bodyFrameRect.size.height = size.height-16;
- return self;
- }
-
- - setFrameRectForMask
- {
- maskFrameRect.size.width = bodyFrameRect.size.width;
- maskFrameRect.size.height = bodyFrameRect.size.height;
- return self;
- }
-
- //bodyFrameRect is actual size of real image inside a black image
- // 8 pixels bigger on all sides
- //bodyPosition is where the actual image will be composited
-
- - drawBody
- {
-
- NXPoint offset;
- NXRect adjustedRect={0.0,0.0,bodyFrameRect.size.width+16,
- bodyFrameRect.size.height+16};
-
- if (bodyPosition.x < (bounds.size.width + bodyFrameRect.size.width) &&
- bodyPosition.x > (bounds.origin.x - (bodyFrameRect.size.width + 1)) &&
- bodyPosition.y < (bounds.size.height + bodyFrameRect.size.width) &&
- bodyPosition.y > (bounds.origin.y-(bodyFrameRect.size.height + 1))){
-
-
- [self setVoidRect:bodyIndex];
-
- offset.x = bodyPosition.x - 8;
- offset.y = bodyPosition.y - 8;
-
- [currentImage composite:NX_COPY fromRect:&adjustedRect
- toPoint:&offset];
- }
-
- return self;
- }
-
- - (BOOL)eraseBody
- {
- NXRect maskRect;
-
- if (maskPosition.x < (bounds.size.width + maskFrameRect.size.width) &&
- maskPosition.x > (bounds.origin.x-(maskFrameRect.size.width + 1)) &&
- maskPosition.y < (bounds.size.height + maskFrameRect.size.width) &&
- maskPosition.y > (bounds.origin.y -(maskFrameRect.size.height + 1))){
-
- maskRect.origin.x = maskPosition.x;
- maskRect.origin.y = maskPosition.y;
- maskRect.size.width = maskFrameRect.size.width;
- maskRect.size.height = maskFrameRect.size.height;
-
- PSsetgray(0);
- NXRectFill(&maskRect);
- return NO;
- }
- else{
- return YES;
- }
- }
- //figure out new x,y position for moving object
- - (NXPoint)adjustPositionForBody:(NXPoint)position
- {
- bodyDist = floor((distDelta * bodyDelta) * (distDelta * bodyDelta) * (distDelta * bodyDelta) * (distDelta * bodyDelta));
- bodyDelta++;
- position.x = floor((centerOfScreen.x - (bodyFrameRect.size.width / 2))
- + (bodyDist * cos(theta)));
- position.y = floor((centerOfScreen.y - (bodyFrameRect.size.height / 2))
- + (bodyDist * sin(theta)));
- return position;
- }
-
- - (NXPoint)adjustPositionForMask:(NXPoint)position
- {
- maskDist = floor((distDelta * maskDelta) * (distDelta * maskDelta) * (distDelta * maskDelta) * (distDelta * maskDelta));
- maskDelta++;
-
- position.x = floor((centerOfScreen.x - (maskFrameRect.size.width / 2))
- + (maskDist * cos(theta)));
- position.y = floor((centerOfScreen.y - (maskFrameRect.size.height / 2))
- + (maskDist * sin(theta)));
- return position;
- }
-
-
- //assumes position and size rects have been set for mask and body
- - setVoidRect:(int)index
- {
- AvoidStruct avoidStruct;
- const NXRect bodyRect = {bodyPosition.x,bodyPosition.y,
- bodyFrameRect.size.width,bodyFrameRect.size.height};
-
- //actual image is centered in a black rectangle 8 pixels
- //bigger in each direction
- //since bodyPosition and bodyFrameRect are set to the image
- // that is in the oversized rect, adjust avoidance to
- // real origin of black rectangle and make width and height
- // actual image size plus 8 pixels - this makes the assumption
- //stars are drawn from 0,0 to 8 pixels right and up.
-
- avoidStruct.avoid.origin.x = bodyRect.origin.x-8;
- avoidStruct.avoid.origin.y = bodyRect.origin.y-8;
- avoidStruct.avoid.size.width = bodyRect.size.width+8;
- avoidStruct.avoid.size.height = bodyRect.size.height+8;
- [avoidStorage replaceElementAt:(unsigned int)bodyIndex with:&avoidStruct];
- return self;
- }
- - setBoundsRect:(NXRect *)r
- {
-
- // screen border width is 5 pixels
- // make ship bounds 1 pixel less so that
- // when border shrinks by 1 it won't
- // affect objects - bounds will catch up
-
- NXSetRect(&bounds,
- r->origin.x,
- r->origin.y,
- r->size.width,
- r->size.height);
- [self setCenter];
- return self;
- }
- - setCenter
- {
- centerOfScreen.x = (bounds.size.width / 2) + bounds.origin.x;
- centerOfScreen.y = bounds.size.height / 2 + bounds.origin.y;
- return self;
- }
-
- - setAngle:(float)angle;
- {
- theta = angle;
- return self;
-
- }
- - setAvoidStorage:(Storage *)storageObject
- {
- avoidStorage = storageObject;
- return self;
- }
-
- - setBodyIndex:(int)index
- {
- bodyIndex = index;
- return self;
- }
-
-
- @end
-